#ifndef GAMEOBJECTS_H
#define GAMEOBJECTS_H

#include "vector.h"
#include "uiDraw.h"

#include <stdlib.h>
#include <iostream>
#include <list>

#define MAX_FRAMES 40
#define MAX_LIVES   4
#define BIG_ROCK_POINT_VALUE 1
#define MED_ROCK_POINT_VALUE 3
#define SML_ROCK_POINT_VALUE 5

using namespace std;

enum {SMALL, MEDIUM, BIG,SHIP_SIZE, LEFT, RIGHT, UP, DOWN};

/**********************************************************
 * MOVEABLE : Movable class
 **********************************************************/
class Movable : public Vector
{
protected:
   bool dead;

public:
   Movable(): Vector() {};
   void draw();

};

/**********************************************************
 * SHOOTABLE : Shootable class
 **********************************************************/
class Shootable : public Movable
{
protected:
   int m_radius;
public:
   Shootable() : Movable() {};
};


/**********************************************************
 * BULLET : Bullet class
 **********************************************************/
class Bullet : public Movable
{
protected:
   bool  m_isDead;
   bool  m_fWrap;
   Point m_startPos;
   Point m_endPos;
   bool  m_isFired;
   int   m_framesToLive;

public:
   Bullet ();
   void draw();
   int  getCountdown() { return m_framesToLive; }
   void subtractFromCountdown() { m_framesToLive--; }

   void setFired(bool isFire) { m_isFired = isFire; }
   void setWrap(bool w) { m_fWrap = w; }
   bool isFired() { return m_isFired; }
};

/**********************************************************
 * SHIP : Ship class
 **********************************************************/
class Ship : public Shootable
{
protected:
   int  m_shipAngle;
   bool m_isAlive;
   int  m_lives;

public:
   Ship();
   void draw();
   void event(int up, int left, int right);
   void fire();
   bool isAlive() { return m_isAlive; }
   void setIsAlive(bool alive) { m_isAlive = alive; }
   void looseLife() { m_lives--; }
   void resetShip();

   double getAngle() { return m_shipAngle; }
   int    getNumLives() { return m_lives;  }
};

/**********************************************************
 * ROCK : Rock class
 **********************************************************/
class Rock : public Shootable
{
protected:
   int m_size;
   int m_radius;
   int m_points;
   int m_rotation;
   bool m_isHit;

public:
   Rock() : Shootable() { m_isHit = false; }
   void operator ++ (int);
   void draw();
   int  getSize() { return m_size; }
   int  getRadius() { return m_radius; }
   bool isHit() { return m_isHit; };
   void setHit(bool hit) { m_isHit = hit; }
};

/**********************************************************
 * BIG ROCK : Big Rock class
 **********************************************************/
class BigRock : public Rock
{
public:
   BigRock();
   bool hit();
 };

/**********************************************************
 * MEDIUM ROCK : Medium Rock class
 **********************************************************/
class MediumRock : public Rock
{
public:
   MediumRock(list <Rock *>::iterator &r, int direction, float speed);
   bool hit();
};

/**********************************************************
 * SMALL ROCK : Small Rock class
 **********************************************************/
class SmallRock : public Rock
{
public:
   SmallRock(list <Rock *>::iterator &r, int direction, float speed);
   bool hit();
};

/**********************************************************
 * SCORE : Score class
 **********************************************************/
class Score
{
private:
   Point m_scoreLocation;
   int   m_numLifes;
   Point m_lifesLocation[3];
   int   m_score;

public:
   Score();
   void  setScore(int score) { m_score = score; }
   Point getPoint() { return m_scoreLocation;   }
   int   getScore() { return m_score;           }
   void  addScore(int add) { m_score += add;    }
   void  drawScore();
   void  drawLifes();
};

#endif // GAMEOBJECTS_H
